<?php

class Runtime {

	private static $pluginId;

	/**
	 * Installo plugin
	 *
	 * @param String plugin id
	 */
	public function install($plugin){
		Register::$plugins[$plugin]['Status']='INSTALLED';
		//load plugin.php file
		unset($PRSP);
		unset($extension);
		Runtime::setPluginId($plugin);
		include_once PLUGINS_PATH . '/' . $plugin . '/plugin.php';
		//check plugin is enable 
		if( isset($PRSP['Enabled']) && $PRSP['Enabled'] ){
			Register::$plugins [$plugin]['Enabled'] = true;
			//load depends
			if (isset ( $PRSP ['Depends'] ) && is_array ( $PRSP ['Depends'] )) {
				Register::$plugins [$plugin]['Depends'] = $PRSP ['Depends'];
			}
			//load version
			if ( isset ( $PRSP ['Version'] ) ){
				Register::$plugins [$plugin]['Version'] = $PRSP ['Version'];
			}
			//load activator
			if ( isset ( $PRSP ['Activator'] ) ){
				Register::$plugins [$plugin]['Activator'] = $PRSP ['Activator'];
			}
			//check auto start
			if ( isset ( $PRSP ['AutoStart'] ) && $PRSP ['AutoStart'] ){
				Register::$plugins [$plugin]['AutoStart'] = true;
			}
			//extension points registed
			if( isset($extension) && is_array($extension) ){
				foreach ( array_keys($extension) as $extPlugin ) {
					if( is_array($extension[$extPlugin]) ){
						foreach ( array_keys($extension[$extPlugin]) as $extensionName ) {
							if(is_array($extension[$extPlugin][$extensionName])){
								foreach ( $extension[$extPlugin][$extensionName] as $key => $value ){
									Register::$extensions[$extensionName.'@'.$extPlugin][$plugin][$key] = $value;
								}
							}else if( !isset(Register::$$extensions) ){
								die( 'Can not registe Plugin Extension Point : Plugin "'.$extensions.'" not found!' );
							}else{
								array_push( Register::$$extensions[$extensionName.'@'.$extPlugin], $extension[$extPlugin][$extensionName] );
							}
						}
					}
				}
			}
			Register::$plugins[$plugin]['Status']='RESOLVED';
		}
	}
	
	/**
	 * Start plugin
	 *
	 * @param String plugin id
	 */
	public function start($plugin) {
		if( !isset(Register::$plugins[$plugin]) ){
			die("Plugin not found : '$plugin'");
		}else if( Register::$plugins[$plugin]['Status']==='INSTALLED' ){
			die("Plugin can't be resolved : '$plugin'");
		}else if (Register::$plugins[$plugin]['Status']!=='ACTIVE') {
			Register::$plugins[$plugin]['Status']='STARTING';
			//start plugins by depends
			foreach (Register::$plugins[$plugin]['Depends'] as $subPlugin){
				if(array_key_exists($subPlugin, Register::$plugins)){
					Runtime::start ( $subPlugin );
				}
			}
			Runtime::loadConfigure($plugin);
			Runtime::loadLibrary($plugin);
			Runtime::loadActivator( $plugin );
			//run start
			$className = str_replace('.','_',$plugin).'_Activator';
			if( class_exists($className) && method_exists($className,'start') ){
				Runtime::setPluginId($plugin);
				call_user_method('start',$className);
				Runtime::setPluginId(null);
			}
			//record start plugin name
			Register::$startPluginList[] = $plugin;
			Register::$plugins[$plugin]['Status']='ACTIVE';
		}
	}
	
	/**
	 * Load Activator Class
	 *
	 * @param String $plugin
	 */
	private function loadActivator( $plugin ){
		if( isset(Register::$plugins [$plugin]['Activator']) ){
			$filename = PLUGINS_PATH . '/' . $plugin . '/'.Register::$plugins [$plugin]['Activator'];
			$className = str_replace('.','_',$plugin).'_Activator';
			//load activator
			if( !class_exists($className) && is_file($filename) ){
				ClassLoader::loadImplements($filename, $className, 'PrspActivator');
			}
		}
	}
	
	/**
	 * Stop plugin
	 *
	 * @param String plugin id
	 */
	public function stop($plugin) {
		if ( Register::$plugins[$plugin]['Status']==='ACTIVE' ) {
			Register::$plugins[$plugin]['Status']='STOPPING';
			//run stop
			$className = str_replace('.','_',$plugin).'_Activator';
			if( class_exists($className) && method_exists($className,'start') ){
				Runtime::setPluginId($plugin);
				call_user_method('stop',$className);
				Runtime::setPluginId(null);
			}
			Register::$plugins[$plugin]['Status']='CLOSE';
		}
	}
	
	/**
	 * Load plugin's library ane change status to ACTIVE
	 *
	 * @param String plugin id
	 */
	public function loadLibrary($pluginId) {
		//auto load library
		$dir = PLUGINS_PATH . '/' . $pluginId . LIBRARY_FOLDER;
		if (is_dir ( $dir )) {
			Runtime::setPluginId($pluginId);
			//search library's folder
			$files = @opendir ( $dir );
			while ( ($file = readdir ( $files )) != false ) {
				if ( substr($file,0,1)!== '.' && eregi(".php$",$file) && is_file($dir.'/'.$file) ){
					include_once $dir.'/'.$file;
					$loadClass = get_declared_classes();
					if( is_subclass_of( $loadClass[count($loadClass)-1], 'PrspLibrary') ){
						call_user_method('initial', $loadClass[count($loadClass)-1]);
					}
				}
			}
			closedir ( $files );
			Runtime::setPluginId(null);
		}
		Register::$plugins[$pluginId]['Status']='ACTIVE';
	}
	
	/**
	 * Load plugin's configures
	 *
	 * @param String plugin id
	 */
	public function loadConfigure($pluginId) {
		//configure auto loading
		$dir = PLUGINS_PATH . '/' . $pluginId . CONFIG_FOLDER;
		if (is_dir ( $dir )) {
			Runtime::setPluginId($pluginId);
			//掃描lib目錄
			$files = @opendir ( $dir );
			while ( ($file = readdir ( $files )) != false ) {
				if ( substr($file,0,1)!== '.' && eregi(".php$",$file) && is_file($dir.'/'.$file) ){
					include_once $dir.'/'.$file;
				}
			}
			closedir ( $files );
			Runtime::setPluginId(null);
		}
	}
	
	/**
	 * Use include_once php function invoke this file
	 *
	 * @param String php filename
	 * @param String plugin id
	 * @return boolean success or fail
	 */
	public function invoke($phpfile, $plugin=null){
		if( $plugin==null ){
			$plugin = Runtime::getPluginId();
		}
		if( is_file(Runtime::getResourcePath($phpfile, $plugin)) ){
			$tmp = Runtime::getPluginId();
			Runtime::setPluginId($plugin);
			Runtime::start($plugin);
			include_once Runtime::getResourcePath($phpfile);
			Runtime::setPluginId($tmp);
			return true;
		}
		return false;
	}
	
	/**
	 * To obtain the absolute URL path by plugin id 
	 *
	 * @param String filename
	 * @param String plugin id
	 * @return String
	 */
	public function getResourceUrl( $filename, $pluginId=null ){
		if( $pluginId==null ){
			$pluginId = Runtime::getPluginId();
		}
		return 'http://'.$_SERVER['SERVER_NAME'].PLUGINS_FOLDER.'/'.$pluginId.$filename;
	}
	
	/**
	 * To obtain the absolute file system path by plugin id 
	 *
	 * @param String filename
	 * @param String plugin id
	 * @return String
	 */
	public function getResourcePath( $filename, $pluginId=null ){
		if( $pluginId==null ){
			$pluginId = Runtime::getPluginId();
		}
		return PLUGINS_PATH.'/'.$pluginId.$filename;
	}
	
	/**
	 * Set runtime plugin id
	 *
	 * @param String plugin id
	 */
	public function setPluginId($id) {
		if( $id==null ){
			Runtime::$pluginId = 'Framework_'.$GLOBALS['PRSP']['Version'];
		}else{
			Runtime::$pluginId = $id;
		}
	}
	
	/**
	 * Get runtime plugin id
	 *
	 * @return String plugin id
	 */
	public function getPluginId() {
		return Runtime::$pluginId;
	}

}

?>